﻿#include "ais_camera.h"
#include "kernel/transform.h"

#define PI 3.1415926535

CAGD::AIS_Camera::AIS_Camera(Handle(GeomPoint) pos) : AIS_Point(pos)
{
    // 设置为不可交互
    m_info.active = false;
    m_info.psize = 10;
    m_info.smooth = false;
    m_info.color = {1.0, 1.0, 1.0, 0.3};

    // 创建一个操作杆，以当前点为起点，创建一个新的端点
    auto pole = Handle(AIS_Pole)(new AIS_Pole(pos, Handle(GeomPoint)(new GeomPoint(pos->Point() * 0.9))));
    m_context.CreateObject(pole);
    AddChild(pole);

    UpdateCameraVectors();
}

CAGD::BMat4x4 CAGD::AIS_Camera::GetViewMatrix() const
{
    auto pole = dynamic_cast<AIS_Pole *>(GetChild(AIS_Type::POLE));
    return Transform::LookAt(m_vertex->Geom()->Point(), pole->GetPoints()[1]->Point(), m_up);
}

void CAGD::AIS_Camera::UpdateInfo()
{
    // do nothing
}

CAGD::AIS_Type CAGD::AIS_Camera::GetType() const
{
    return AIS_Type::CAMERA;
}

void CAGD::AIS_Camera::RecvMessage(Message mess)
{
    // 先调用默认接收函数
    AIS_Base::RecvMessage(mess);

    // none 的目的是让未选中的操作轴都隐藏
    switch (mess)
    {
    case CAGD::Message::MOVE_PARENT: {
        UpdateCameraVectors();
        break;
    }
    default:
        break;
    }
}

void CAGD::AIS_Camera::UpdateCameraVectors()
{
    // 获得相机信息
    auto pos = m_vertex->Geom()->Point();
    auto origin = dynamic_cast<AIS_Pole *>(GetChild(AIS_Type::POLE))->GetPoints()[1]->Point();
    float distance = pos.Distance(origin);

    // 计算欧拉角
    m_front = (origin - pos).Normalized();
    m_pitch = acos(m_front.Z());
    m_yaw = acos(m_front.X() / sin(m_pitch));
    if (m_front.Y() < 0)
        m_yaw = PI * 2 - m_yaw;

    // 然后叉乘计算另外两个方向
    m_right = (m_front % BVecf{0, 0, 1}).Normalized();
    m_up = (m_right % m_front).Normalized();
}
